<?php

namespace app\company\controller;

use app\common\controller\CompanyController;
use app\common\enum\order\OrderStatus;
use app\common\enum\order\OrderType;
use app\common\enum\order\PickStatus;
use app\common\exception\BaseException;
use app\common\model\CompanyWarehouse;
use app\common\service\annotation\ControllerAnnotation;
use app\common\service\annotation\NodeAnnotation;
use app\company\model\CompanyOrder;
use app\company\model\CompanyOrderDetail;
use app\company\model\CompanyPickOrder;
use app\company\model\CompanyPickOrderDetail;
use app\company\model\Delivery as DeliveryModel;
use app\Request;
use think\App;
use think\response\Json;

/**
 * @ControllerAnnotation(title="配送单")
 */
class Task extends CompanyController
{
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->model = new CompanyOrder();
    }

    /**
     * @NodeAnnotation(title="配送任务列表")
     * 物流单指订单中销售属性单订单
     */
    public function list():Json
    {
        $get = $this->request->get();
        [, $where] = $this->buildSearchParams($get);
        $list = (new DeliveryModel())->with([
            'middleOrder'=>function ($query) {
                $query->with([
                    'orders'=>function ($query) {
                        $query->with([
                            'detail'   => function ($query)
                            {
                                $query->with([
                                    'goods'     => function ($query)
                                    {
                                        $query->field('id,image,name,code69')->withTrashed();
                                    },
                                    'goodsSpec' => function ($query)
                                    {
                                        $query->field('id,image,name,unit,driver_money,sku')->withTrashed();
                                    },
                                    'warehouse' => function ($query)
                                    {
                                        $query->field('id,name')->withTrashed();
                                    },
                                ]);
                            },
                            'store'    => function ($query)
                            {
                                $query->field('id,name,address,contact,phone');
                            },
                            'dealer'   => function ($query)
                            {
                                $query->field('id,name');
                            },
                            'salesman' => function ($query)
                            {
                                $query->field('id,rename,phone');
                            },
                            'driver'   => function ($query)
                            {
                                $query->field('id,name');
                            }
                        ]);
                    }
                ]);
            },
            'driver'
        ])->where($where)->where($this->defaultWhere)->order('id desc');
        // 合计配送收益
        $list = $this->each($list->paginate($get['limit']??15));
        $list = $list->toArray();
        return $this->success($list);
    }

    public function each($list)
    {
        return $list->each(function ($vo)
        {
            /*$vo->middleOrder()->select()->each(function ($item) use (&$driver_money)
            {
                $item->order = $item->orders()->select()->each(function ($goods) use (&$goods_driver_money){
                    $goods->detail = $goods->detail()->select()->each(function ($spec) use (&$spec_driver_money){
                        $spec->goodsSpec = $spec->goodsSpec()->withTrashed()->field('id,driver_money')->find();
                        // 收益
                        $spec->goodsSpec->driver_money = $spec->goodsSpec->driver_money * $spec->num;
//                        $spec_driver_money += $spec->goodsSpec->driver_money;
//                        $spec->warehouse = (new CompanyWarehouse())->where('id',$spec->company_warehouse_id)->value('name')??'';
                    });
//                    $goods_driver_money += $spec_driver_money;
                });
//                $driver_money += $goods_driver_money;
            });*/
            // 配送收益
//            $vo->driver_money = round($driver_money,2);
            return $vo;
        });
    }

    /**
     * @NodeAnnotation(title="订单列表")
     * 配送单指销售订单已经分配给司机的订单
     */
    public function listOld(): Json
    {
        list($limit, $where) = $this->buildSearchParams();
        $list = $this->model->with([
                                           'detail'   => function ($query)
                                           {
                                               $query->with([
                                                                    'goods'     => function ($query)
                                                                    {
                                                                        $query->field('id,image,name')->withTrashed();
                                                                    },
                                                                    'goodsSpec' => function ($query)
                                                                    {
                                                                        $query->field('id,image,name,unit')->withTrashed();
                                                                    }
                                                            ]);
                                           },
                                           'store'    => function ($query)
                                           {
                                               $query->field('id,name,address');
                                           },
                                           'dealer'   => function ($query)
                                           {
                                               $query->field('id,name');
                                           },
                                           'salesman' => function ($query)
                                           {
                                               $query->field('id,rename');
                                           },
                                           'driver'   => function ($query)
                                           {
                                               $query->field('id,name');
                                           }
                                   ])->where('order_type', OrderType::SALES)
//                            ->where('order_status', OrderStatus::PASS)
                            ->where($where)
                            ->where('pid', '<>', 0)
                            ->where('driver_id', '<>', 0)
                            ->where($this->defaultWhere)
                            ->paginate($get['limit'] ?? 10)
                            ->toArray();
        return $this->success($list);
    }

    /**
     * @NodeAnnotation(title="订单拣货")
     */
    public function pick(Request $request,$id=0): Json
    {
        try {
            $this->checkPost();
            $model = (new DeliveryModel());
            // 查询记录
            $row = $model->find($id);
            if (empty($row)) throw new BaseException(['message' => '订单不存在']);
            $ids = explode(',',$row->company_order_ids);
            $this->model->transaction(function () use ($ids,$id,$model)
            {
                // 判断是否已经存在捡货单
//                array_walk($ids, function ($v)
//                {
//                    //查询捡货详情
//                    $pickOrderDetail = CompanyPickOrderDetail::where('company_order_id', $v)->find();
//                    if ($pickOrderDetail) {
//                        $orderNo = $this->model->where('id', $v)->value('order_no');
//                        throw new BaseException(['message' => '订单【' . $orderNo . '】已存在拣货单中']);
//                    }
//                });
                foreach ($ids as $k => $v){
                    //查询捡货详情
                    $pickOrderDetail = CompanyPickOrderDetail::where('company_order_id', $v)->find();
                    if ($pickOrderDetail) unset($ids[$k]);
                }
                // 过滤订单
                $orderIds = $this->model->where('id', 'in', $ids)
//                                        ->where('order_status', OrderStatus::PASS)
                                        ->where('order_status', OrderStatus::BEING)
                                        ->where('check_status', 2)
                                        ->where('order_type', OrderType::SALES)
                                        ->column('id');
                if (empty($orderIds)) throw new BaseException(['message' => '该配送单包含的订单已存在拣货单中,无法重复拣货']);
                // 生成分拣单
                $outOrder = new CompanyPickOrder();
                $outOrder->save([
                                        'company_id'        => $this->companyId,
                                        'pick_order_no'     => generateOrderNo('PK'),
                                        'company_order_ids' => implode(',', $orderIds),
                                        'order_num'         => count($orderIds),
                                        'pick_num'          => CompanyOrderDetail::whereIn('company_order_id',
                                                                                           $orderIds)->sum('num'),
                                        'true_pick_num'     => CompanyOrderDetail::whereIn('company_order_id',
                                                                                           $orderIds)->sum('num')
                                ]);
                // 生成分拣单详情表
                if ($outOrder) {
                    $detail = array_map(function ($id) use ($outOrder)
                    {
                        $dealerId = $this->model->where('id', $id)->value('dealer_id');
                        return [
                                'company_pick_order_id' => $outOrder->id,
                                'company_order_id'      => $id,
                                'dealer_id'      => $dealerId,
                        ];
                    }, $orderIds);
                    $outOrder->detail()->saveAll($detail);
                }
                // 修改拣货状态
                $model->where('id', $id)->save(['pick_status' => PickStatus::PICKED]);
                $this->model->where('id', 'in',$ids)->save(['pick_status' => PickStatus::PICKED]);
            });
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success('拣货成功');
    }

    /**
     * @NodeAnnotation(title="配送单驳回")
     * @param Request $request
     * @return Json
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function review(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        if(empty($post['id'])) return $this->error('参数错误');
        $deliveryModel = new DeliveryModel();
        $info = $deliveryModel->where('id',$post['id'])->find();
        if(!$info || $info->pick_status != 1) return $this->error('数据错误');
        if($info->status != 1) return $this->error('该配送单已配送完成，无法再驳回');
        try{
            $this->model->transaction(function () use ($deliveryModel,$info){
                // 把配送单取消掉
                $info->save([
                    'review_status' => DeliveryModel::REVIEW_TWO,
                    'review_id' => $this->uid,
                    'review_time' => time(),
                ]);
                // 把订单还原（司机ID那列归0）
                $this->model->where('id','in',explode(',',$info->company_order_ids))->save([
                    'driver_id' => 0,
                    'allow_status' => 1,
                ]);
            });
            return $this->success('驳回成功');
        }catch(\Exception $e){
            return $this->error('驳回失败'.$e->getMessage());
        }
    }
}